package de.jmda.gui;

import javax.lang.model.element.Element;

import de.jmda.mproc.ProcessingUtilities;

public abstract class ImageFilenameFactory
{
	/**
	 * Maps {@link Element} instances to UML image file names.
	 *
	 * @param element
	 * @return
	 */
	public static String getImageFilename(Element element, String filenameSuffix)
	{
		if (ProcessingUtilities.isClassKind(element))
		{
			Element enclosingElement = element.getEnclosingElement();
			
			if (ProcessingUtilities.isPackageKind(enclosingElement))
			{
				if (ProcessingUtilities.isVisibilityDefault(element))
				{
					if (ProcessingUtilities.isFinal(element))
					{
						if (ProcessingUtilities.isStatic(element))
						{
							return "jMDA.class.default.final.static." + filenameSuffix;
						}
						else
						{
							return "jMDA.class.default.final.static." + filenameSuffix;
						}
					}
					else
					{
						if (ProcessingUtilities.isAbstract(element))
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return "jMDA.class.default.abstract.static." + filenameSuffix;
							}
							else
							{
								return "jMDA.class.default.abstract." + filenameSuffix;
							}
						}
						else
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return "jMDA.class.default.static." + filenameSuffix;
							}
							else
							{
								return "jMDA.class.default." + filenameSuffix;
							}
						}
					}
				}
				else if (ProcessingUtilities.isVisibilityPrivate(element))
				{
					if (ProcessingUtilities.isFinal(element))
					{
						if (ProcessingUtilities.isStatic(element))
						{
							return "jMDA.class.private.final.static." + filenameSuffix;
						}
						else
						{
							return "jMDA.class.private.final." + filenameSuffix;
						}
					}
					else
					{
						if (ProcessingUtilities.isAbstract(element))
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return "jMDA.class.private.abstract.static." + filenameSuffix;
							}
							else
							{
								return "jMDA.class.private.abstract." + filenameSuffix;
							}
						}
						else
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return "jMDA.class.private.static." + filenameSuffix;
							}
							else
							{
								return "jMDA.class.private." + filenameSuffix;
							}
						}
					}
				}
				else if (ProcessingUtilities.isVisibilityProtected(element))
				{
					if (ProcessingUtilities.isFinal(element))
					{
						if (ProcessingUtilities.isStatic(element))
						{
							return "jMDA.class.protected.final.static." + filenameSuffix;
						}
						else
						{
							return "jMDA.class.protected.final." + filenameSuffix;
						}
					}
					else
					{
						if (ProcessingUtilities.isAbstract(element))
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return "jMDA.class.protected.abstract.static." + filenameSuffix;
							}
							else
							{
								return "jMDA.class.protected.abstract." + filenameSuffix;
							}
						}
						else
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return "jMDA.class.protected.static." + filenameSuffix;
							}
							else
							{
								return "jMDA.class.protected." + filenameSuffix;
							}
						}
					}
				}
				else if (ProcessingUtilities.isVisibilityPublic(element))
				{
					if (ProcessingUtilities.isFinal(element))
					{
						if (ProcessingUtilities.isStatic(element))
						{
							return "jMDA.class.public.final.static." + filenameSuffix;
						}
						else
						{
							return "jMDA.class.public.final." + filenameSuffix;
						}
					}
					else
					{
						if (ProcessingUtilities.isAbstract(element))
						{
							return "jMDA.class.public.abstract." + filenameSuffix;
						}
						else
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return "jMDA.class.public.static." + filenameSuffix;
							}
							else
							{
								return "jMDA.class.public." + filenameSuffix;
							}
						}
					}
				}
				else
				{
					throw new IllegalStateException(
							"unexpected visibility for " + element.toString());
				}
			}
			else
			{
				if (ProcessingUtilities.isVisibilityDefault(element))
				{
					if (ProcessingUtilities.isFinal(element))
					{
						if (ProcessingUtilities.isStatic(element))
						{
							return "jMDA.class.inner.default.final.static." + filenameSuffix;
						}
						else
						{
							return "jMDA.class.inner.default.final." + filenameSuffix;
						}
					}
					else
					{
						if (ProcessingUtilities.isAbstract(element))
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return "jMDA.class.inner.default.abstract.static." + filenameSuffix;
							}
							else
							{
								return "jMDA.class.inner.default.abstract." + filenameSuffix;
							}
						}
						else
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return "jMDA.class.inner.default.static." + filenameSuffix;
							}
							else
							{
								return "jMDA.class.inner.default." + filenameSuffix;
							}
						}
					}
				}
				else if (ProcessingUtilities.isVisibilityPrivate(element))
				{
					if (ProcessingUtilities.isFinal(element))
					{
						if (ProcessingUtilities.isStatic(element))
						{
							return "jMDA.class.inner.private.final.static." + filenameSuffix;
						}
						else
						{
							return "jMDA.class.inner.private.final." + filenameSuffix;
						}
					}
					else
					{
						if (ProcessingUtilities.isAbstract(element))
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return "jMDA.class.inner.private.abstract.static." + filenameSuffix;
							}
							else
							{
								return "jMDA.class.inner.private.abstract." + filenameSuffix;
							}
						}
						else
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return "jMDA.class.inner.private.static." + filenameSuffix;
							}
							else
							{
								return "jMDA.class.inner.private." + filenameSuffix;
							}
						}
					}
				}
				else if (ProcessingUtilities.isVisibilityProtected(element))
				{
					if (ProcessingUtilities.isFinal(element))
					{
						if (ProcessingUtilities.isStatic(element))
						{
							return "jMDA.class.inner.protected.final.static." + filenameSuffix;
						}
						else
						{
							return "jMDA.class.inner.protected.final." + filenameSuffix;
						}
					}
					else
					{
						if (ProcessingUtilities.isAbstract(element))
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return "jMDA.class.inner.protected.abstract.static." + filenameSuffix;
							}
							else
							{
								return "jMDA.class.inner.protected.abstract." + filenameSuffix;
							}
						}
						else
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return "jMDA.class.inner.protected.static." + filenameSuffix;
							}
							else
							{
								return "jMDA.class.inner.protected." + filenameSuffix;
							}
						}
					}
				}
				else if (ProcessingUtilities.isVisibilityPublic(element))
				{
					if (ProcessingUtilities.isFinal(element))
					{
						if (ProcessingUtilities.isStatic(element))
						{
							return "jMDA.class.inner.public.final.static." + filenameSuffix;
						}
						else
						{
							return "jMDA.class.inner.public.final." + filenameSuffix;
						}
					}
					else
					{
						if (ProcessingUtilities.isAbstract(element))
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return "jMDA.class.inner.public.abstract.static." + filenameSuffix;
							}
							else
							{
								return "jMDA.class.inner.public.abstract." + filenameSuffix;
							}
						}
						else
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return "jMDA.class.inner.public.static." + filenameSuffix;
							}
							else
							{
								return "jMDA.class.inner.public." + filenameSuffix;
							}
						}
					}
				}
				else
				{
					throw new IllegalStateException(
							"unexpected visibility for " + element.toString());
				}
			}
		}
		else if (ProcessingUtilities.isInterfaceKind(element))
		{
			Element enclosingElement = element.getEnclosingElement();
			
			if (ProcessingUtilities.isPackageKind(enclosingElement))
			{
				if (ProcessingUtilities.isVisibilityDefault(element))
				{
					return "jMDA.interface.default." + filenameSuffix;
				}
				else if (ProcessingUtilities.isVisibilityPublic(element))
				{
					return "jMDA.interface.public." + filenameSuffix;
				}
				else
				{
					throw new IllegalStateException(
							"unexpected visibility for " + element.toString());
				}
			}
			else
			{
				if (ProcessingUtilities.isVisibilityDefault(element))
				{
					return "jMDA.interface.inner.default." + filenameSuffix;
				}
				else if (ProcessingUtilities.isVisibilityProtected(element))
				{
					return "jMDA.interface.inner.protected." + filenameSuffix;
				}
				else if (ProcessingUtilities.isVisibilityPrivate(element))
				{
					return "jMDA.interface.inner.private." + filenameSuffix;
				}
				else if (ProcessingUtilities.isVisibilityPublic(element))
				{
					return "jMDA.interface.inner.public." + filenameSuffix;
				}
				else
				{
					throw new IllegalStateException(
							"unexpected visibility for " + element.toString());
				}
			}
		}
		else if (ProcessingUtilities.isEnumKind(element))
		{
			Element enclosingElement = element.getEnclosingElement();
			
			if (ProcessingUtilities.isPackageKind(enclosingElement))
			{
				if (ProcessingUtilities.isVisibilityDefault(element))
				{
					return "jMDA.enum.default." + filenameSuffix;
				}
				else if (ProcessingUtilities.isVisibilityPublic(element))
				{
					return "jMDA.enum.public." + filenameSuffix;
				}
				else
				{
					throw new IllegalStateException(
							"unexpected visibility for " + element.toString());
				}
			}
			else
			{
				if (ProcessingUtilities.isVisibilityDefault(element))
				{
					return "jMDA.enum.inner.default." + filenameSuffix;
				}
				else if (ProcessingUtilities.isVisibilityProtected(element))
				{
					return "jMDA.enum.inner.protected." + filenameSuffix;
				}
				else if (ProcessingUtilities.isVisibilityPrivate(element))
				{
					return "jMDA.enum.inner.private." + filenameSuffix;
				}
				else if (ProcessingUtilities.isVisibilityPublic(element))
				{
					return "jMDA.enum.inner.public." + filenameSuffix;
				}
				else
				{
					throw new IllegalStateException(
							"unexpected visibility for " + element.toString());
				}
			}
		}
		else if (ProcessingUtilities.isAnnotationKind(element))
		{
			Element enclosingElement = element.getEnclosingElement();
			
			if (ProcessingUtilities.isPackageKind(enclosingElement))
			{
				if (ProcessingUtilities.isVisibilityDefault(element))
				{
					return "jMDA.annotation.default." + filenameSuffix;
				}
				else if (ProcessingUtilities.isVisibilityPublic(element))
				{
					return "jMDA.annotation.public." + filenameSuffix;
				}
				else
				{
					throw new IllegalStateException(
							"unexpected visibility for " + element.toString());
				}
			}
			else
			{
				if (ProcessingUtilities.isVisibilityDefault(element))
				{
					return "jMDA.annotation.inner.default." + filenameSuffix;
				}
				else if (ProcessingUtilities.isVisibilityProtected(element))
				{
					return "jMDA.annotation.inner.protected." + filenameSuffix;
				}
				else if (ProcessingUtilities.isVisibilityPrivate(element))
				{
					return "jMDA.annotation.inner.private." + filenameSuffix;
				}
				else if (ProcessingUtilities.isVisibilityPublic(element))
				{
					return "jMDA.annotation.inner.public." + filenameSuffix;
				}
				else
				{
					throw new IllegalStateException(
							"unexpected visibility for " + element.toString());
				}
			}
		}
		else if (ProcessingUtilities.isFieldKind(element))
		{
			if (ProcessingUtilities.isVisibilityDefault(element))
			{
				if (ProcessingUtilities.isFinal(element))
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return "jMDA.field.default.final.static." + filenameSuffix;
					}
					else
					{
						return "jMDA.field.default.final." + filenameSuffix;
					}
				}
				else
				{
					return "jMDA.field.default." + filenameSuffix;
				}
			}
			else if (ProcessingUtilities.isVisibilityPrivate(element))
			{
				if (ProcessingUtilities.isFinal(element))
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return "jMDA.field.private.final.static." + filenameSuffix;
					}
					else
					{
						return "jMDA.field.private.final." + filenameSuffix;
					}
				}
				else
				{
					return "jMDA.field.private." + filenameSuffix;
				}
			}
			else if (ProcessingUtilities.isVisibilityProtected(element))
			{
				if (ProcessingUtilities.isFinal(element))
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return "jMDA.field.protected.final.static." + filenameSuffix;
					}
					else
					{
						return "jMDA.field.protected.final." + filenameSuffix;
					}
				}
				else
				{
					return "jMDA.field.protected." + filenameSuffix;
				}
			}
			else if (ProcessingUtilities.isVisibilityPublic(element))
			{
				if (ProcessingUtilities.isFinal(element))
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return "jMDA.field.public.final.static." + filenameSuffix;
					}
					else
					{
						return "jMDA.field.public.final." + filenameSuffix;
					}
				}
				else
				{
					return "jMDA.field.public." + filenameSuffix;
				}
			}
			else
			{
				throw new IllegalStateException(
						"unexpected visibility for " + element.toString());
			}
		}
		else if (ProcessingUtilities.isMethodKind(element))
		{
			if (ProcessingUtilities.isVisibilityDefault(element))
			{
				if (ProcessingUtilities.isFinal(element))
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return "jMDA.method.default.final.static." + filenameSuffix;
					}
					else
					{
						return "jMDA.method.default.final." + filenameSuffix;
					}
				}
				else
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return "jMDA.method.default.static." + filenameSuffix;
					}
					else
					{
						if (ProcessingUtilities.isAbstract(element))
						{
							return "jMDA.method.default.abstract." + filenameSuffix;
						}
						else
						{
							return "jMDA.method.default." + filenameSuffix;
						}
					}
				}
			}
			else if (ProcessingUtilities.isVisibilityPrivate(element))
			{
				if (ProcessingUtilities.isFinal(element))
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return "jMDA.method.private.final.static." + filenameSuffix;
					}
					else
					{
						return "jMDA.method.private.final." + filenameSuffix;
					}
				}
				else
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return "jMDA.method.private.static." + filenameSuffix;
					}
					else
					{
						// there are no private abstract methods
						return "jMDA.method.private." + filenameSuffix;
					}
				}
			}
			else if (ProcessingUtilities.isVisibilityProtected(element))
			{
				if (ProcessingUtilities.isFinal(element))
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return "jMDA.method.protected.final.static." + filenameSuffix;
					}
					else
					{
						return "jMDA.method.protected.final." + filenameSuffix;
					}
				}
				else
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return "jMDA.method.protected.static." + filenameSuffix;
					}
					else
					{
						if (ProcessingUtilities.isAbstract(element))
						{
							return "jMDA.method.protected.abstract." + filenameSuffix;
						}
						else
						{
							return "jMDA.method.protected." + filenameSuffix;
						}
					}
				}
			}
			else if (ProcessingUtilities.isVisibilityPublic(element))
			{
				if (ProcessingUtilities.isFinal(element))
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return "jMDA.method.public.final.static." + filenameSuffix;
					}
					else
					{
						return "jMDA.method.public.final." + filenameSuffix;
					}
				}
				else
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return "jMDA.method.public.static." + filenameSuffix;
					}
					else
					{
						if (ProcessingUtilities.isAbstract(element))
						{
							return "jMDA.method.public.abstract." + filenameSuffix;
						}
						else
						{
							return "jMDA.method.public." + filenameSuffix;
						}
					}
				}
			}
			else
			{
				throw new IllegalStateException(
						"unexpected visibility for " + element.toString());
			}
		}
		else if (ProcessingUtilities.isPackageKind(element))
		{
			return "jMDA.package." + filenameSuffix;
		}
		else if (ProcessingUtilities.isEnumConstantKind(element))
		{
			return "jMDA.enum.default." + filenameSuffix;
		}
		else
		{
			throw new IllegalStateException(
					"unexpected element type " + element.toString());
		}
  }
}